//
//  SearchUsers.m
//  iCan - iPhone Context-Aware Navigation
//  Carnegie Mellon University - 18-842 Distributed Systems
//
//  Created by Andrew Santell on 3/26/12.
//  Copyright (c) 2012 Andrew Santell. All rights reserved.

/* Search Users Table View Controller.  Allows user to query all checked-in users */

#import "SearchUsers.h"
#import "Users.h"
#import "UserDetails.h"
#import "SpinnerView.h"
#import "iCanAppDelegate.h"
#import "iCanViewController.h"

@interface SearchUsers ()

@end

@implementation SearchUsers

@synthesize users, totalArray;
@synthesize result, message;
@synthesize inputStream, outputStream;
@synthesize spinner;
@synthesize appDelegate, badCookie;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    /* Set up user "global variables" */
    appDelegate = [[UIApplication sharedApplication] delegate];
    badCookie = FALSE;
    [self queryUsers];
}

- (void)viewDidUnload
{
    [self setUsers:nil];
    [self setTotalArray:nil];
    [self setResult:nil];
    [self setMessage:nil];
    [self setInputStream:nil];
    [self setOutputStream:nil];
    [self setSpinner:nil];
    [self setAppDelegate:nil];
    [super viewDidUnload];
}


-(void)queryUsers
{
    /* Load spinner on top of screen until receiving network result */
    spinner = [[SpinnerView alloc] init];
    [spinner loadSpinnerIntoView:self.view];
    
    /* Build message to send to network */
    message = @"query_users";
    message = [message stringByAppendingString:@";"];
    message = [message stringByAppendingString:appDelegate.myCookie];
    message = [message stringByAppendingString:@";"];
    message = [message stringByAppendingString:appDelegate.myName];
    message = [message stringByAppendingString:@";"];
    message = [message stringByAppendingString:@"\n"];
    
    /* Disable Back button while connecting to network */
    self.navigationController.navigationBar.userInteractionEnabled = NO;
    
    /* Initiate network connection */
    [self initNetworkCommunication];
}

/* Move the return string into the user array */
-(void)analyzeResult
{
       
    UIAlertView *badCookieAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your session has expired.  Please login again"delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    
    NSLog(@"result = %@", result);
    
    if ([result isEqualToString:@"BAD_COOKIE"])
    { 
        NSLog(@"Bad Cookie");
        badCookie = TRUE;
        [badCookieAlert show];
    }
    
    totalArray = [result componentsSeparatedByString:@";"];
    
    int arrayLength = ([totalArray count]) - 1;
    int i = 0;
    users = [[NSMutableArray alloc] init];
    Users *user = [[Users alloc] init];
    
    while (i < arrayLength)
    {
        NSArray *tempArray = [[totalArray objectAtIndex:i] componentsSeparatedByString:@","];
        NSLog(@"temparray = %@", tempArray);
        user.userName = [tempArray objectAtIndex:0];
        user.fName = [tempArray objectAtIndex:3];
        user.lName = [tempArray objectAtIndex:4];
        user.group = [tempArray objectAtIndex:5];
        
        NSString *unSanitizedStatus = [tempArray objectAtIndex:1];
        user.status = [unSanitizedStatus stringByReplacingOccurrencesOfString:@"%42" withString:@";"];
        
        if ([[tempArray objectAtIndex:2] isEqualToString: @"0"])
        {
            user.available = true;
        }
        else
        {
            user.available = false;
        }
        
        [users addObject:user];
        user = [[Users alloc] init];

        i++;
    }
    
    result = NULL;
    
    /* Reload data view */
    [self.tableView reloadData];
    
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex   
{
    if (badCookie == TRUE)
    {
        badCookie = FALSE;
        result = NULL;
        iCanViewController *mainScreen = [self.storyboard instantiateViewControllerWithIdentifier:@"MainScreen"];
        [self presentViewController:mainScreen animated:YES completion:nil];
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.users count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	/*Setting up the table*/
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UserCell"];
	Users *user = [self.users objectAtIndex:indexPath.row];
    UILabel *nameLabel = (UILabel *) [cell viewWithTag:10];
    nameLabel.text = user.userName;
    UILabel *statusLabel = (UILabel *) [cell viewWithTag:11];
    statusLabel.text = user.status;
    UIImageView *availableView = (UIImageView *) [cell viewWithTag:12];
    
    if (user.available == true)
        availableView.image = [UIImage imageNamed:@"green.png"];
    if (user.available == false)
        availableView.image = [UIImage imageNamed:@"red.png"];

    return cell;  
  
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

/* Populate UserDetails Controller View when row is clicked */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UserDetails *detail = [self.storyboard instantiateViewControllerWithIdentifier:@"Detail"];
	Users *user = [self.users objectAtIndex:indexPath.row];
    detail.fName = user.fName;
    detail.lName = user.lName;
    detail.status = user.status;
    detail.userName = user.userName;
    detail.group = user.group;
    detail.available = user.available;
    [self.navigationController pushViewController:detail animated:YES];
   
}

/* Initiate network connection */
- (void) initNetworkCommunication
{
    
    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)appDelegate.nodeIP, appDelegate.nodePort, &readStream, &writeStream);
    
    inputStream = (__bridge NSInputStream *) readStream;
    outputStream = (__bridge NSOutputStream *) writeStream;
    
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    
    /* Put input and output streams into a run loop */
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    [inputStream open];
    [outputStream open];
    
    /* Put message into a format that can be sent across the network (NSData) */
    NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSASCIIStringEncoding]];
    
    /* Send message to network */
    [outputStream write:[data bytes] maxLength:[data length]];
    
    
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 
{
    /* Create error popup for failed connections */
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to host"delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    
    switch (streamEvent) 
    {
		case NSStreamEventOpenCompleted:
			NSLog(@"Stream opened");
			break;
            
            /* Accept return message from network */
		case NSStreamEventHasBytesAvailable:
            
            if (theStream == inputStream) 
            {
                
                uint8_t buffer[1024];
                int len;
                
                while ([inputStream hasBytesAvailable]) 
                {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) 
                    {
                        
                        result = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                        
                        if (nil != result) 
                        {
                            NSLog(@"Response: %@", result);
                        }
                    }
                }
            }
			break;			
            
		case NSStreamEventErrorOccurred:
            NSLog(@"Can not connect to the host!");
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [spinner removeSpinner];
            [alert show];
            self.navigationController.navigationBar.userInteractionEnabled = YES;
			break;
            
		case NSStreamEventEndEncountered:
            NSLog(@"Closing Connection");
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            self.navigationController.navigationBar.userInteractionEnabled = YES; 
            [spinner removeSpinner];
            [self analyzeResult];
			break;
            
		case NSStreamEventHasSpaceAvailable:
            NSLog (@"Output Buffer is Empty");
            break;
            
        default:
			NSLog(@"Unknown event");
            NSLog(@"Error Result (Should be NULL) = %@", result);
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [spinner removeSpinner];
            self.navigationController.navigationBar.userInteractionEnabled = YES;
            [alert show];
	}
}

@end
